package com.kmt.plaza.sevice.impl;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kmt.plaza.dao.ProductImgMapper;
import com.kmt.plaza.dao.ProductMapper;
import com.kmt.plaza.dao.ProductParamsMapper;
import com.kmt.plaza.dao.ProductSkuMapper;
import com.kmt.plaza.entity.*;
import com.kmt.plaza.sevice.ProductService;
import com.kmt.plaza.utils.PageHelper;
import com.kmt.plaza.vo.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
public class ProductServiceImpl implements ProductService {
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private ProductImgMapper productImgMapper;
    @Autowired
    private ProductSkuMapper productSkuMapper;
    @Autowired
    private ProductParamsMapper productParamsMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    //下面需要对此使用，所以将ObjectMapper定义在这里
    private ObjectMapper objectMapper = new ObjectMapper();
    private Logger logger = LoggerFactory.getLogger(ProductServiceImpl.class);
    //商品推存
    @Override
    public ResultVO listRecommendProducts() {
        logger.info("商品推荐开始......");
        List<ProductVO> productVOS = productMapper.selectRecommendProducts();
        ResultVO resultVO = new ResultVO(ResStatus.OK, "success", productVOS);
        return resultVO;
    }

    //商品基本信息查询
    @Transactional(propagation = Propagation.SUPPORTS)
    public ResultVO getProductBasicInfo(String productId) {
        logger.info("商品基本信息查询开始......");
        try {
            //①根据商品id查询redis
            String productInfo = (String) stringRedisTemplate.boundHashOps("products").get(productId);
            //这里需要将上面得到的字符串转为对象,ObjectMapper作用是将java对象与json格式相互转化
            //②如果redis中查到了商品信息，则直接返回给控制器
            if (productInfo != null) {
                Product product = objectMapper.readValue(productInfo, Product.class);
                //从redis中查询商品的图片信息findAllComments
                String imgStr = (String) stringRedisTemplate.boundHashOps("productImgs").get(productId);
                //将imgStr字符串转换为List
                JavaType javaType1 = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, ProductImg.class);
                List<ProductImg> productImgs = objectMapper.readValue(imgStr, javaType1);
                //从redis中查商品的参数
                String skuStr = (String) stringRedisTemplate.boundHashOps("productSkus").get(productId);
                //将skuStr字符串转化为List
                JavaType javaType2 = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, ProductSku.class);
                List<ProductSku> productSkus = objectMapper.readValue(skuStr, javaType2);
                //封装商品、商品的图片及套餐
                HashMap<String, Object> basicInfo = new HashMap<>();
                basicInfo.put("product", product);
                basicInfo.put("productImgs", productImgs);
                basicInfo.put("productSkus", productSkus);
                return new ResultVO(ResStatus.OK, "success", basicInfo);
            } else {
                //③如果redis中没有查询到商品信息，则查询数据库
                //1、商品基本信息
                Example example = new Example(Product.class);
                Example.Criteria criteria = example.createCriteria();
                criteria.andEqualTo("productId", productId);
                criteria.andEqualTo("productStatus", 1);//productStatus=1表示上架商品
                List<Product> products = productMapper.selectByExample(example);
                if (products.size() > 0) {
                    //将从数据库查到的数据存放到redis
                    Product product1 = products.get(0);
                    String jsonStr = objectMapper.writeValueAsString(product1);
                    stringRedisTemplate.boundHashOps("products").put(productId, jsonStr);
                    //根据商品id查询商品图片
                    Example example1 = new Example(ProductImg.class);
                    Example.Criteria criteria1 = example1.createCriteria();
                    criteria1.andEqualTo("itemId", productId);
                    List<ProductImg> productImgs = productImgMapper.selectByExample(example1);
                    //将商品的图片信息转为字符串保存到redis中
                    stringRedisTemplate.boundHashOps("productImgs").put(productId, objectMapper.writeValueAsString(productImgs));
                    //根剧商品id查询商品参数
                    Example example2 = new Example(ProductSku.class);
                    Example.Criteria criteria2 = example2.createCriteria();
                    criteria2.andEqualTo("productId", productId);
                    criteria2.andEqualTo("status", 1);
                    List<ProductSku> productSkus = productSkuMapper.selectByExample(example2);
                    stringRedisTemplate.boundHashOps("productSkus").put(productId, objectMapper.writeValueAsString(productSkus));
                    HashMap<String, Object> basicInfo = new HashMap<>();
                    basicInfo.put("product", products.get(0));
                    basicInfo.put("productImgs", productImgs);
                    basicInfo.put("productSkus", productSkus);
                    return new ResultVO(ResStatus.OK, "success", basicInfo);

                } else {
                    return new ResultVO(ResStatus.NO, "查询的商品不存在", null);
                }
            }
        } catch (Exception e) {

        }
        return new ResultVO(ResStatus.NO, "查询的商品不存在", null);

    }
    //查询商品列表
    @Override
    public ResultVO selectProductLists(int pageNum, int limit) {
        logger.info("开始查询商品列表......");
        //1、查询总记录数
        Example example = new Example(Product.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("");
        int count = productMapper.selectCountByExample(example);
        //2、计算总页数
        int pageCount = count % limit == 0 ? count / limit : (count / limit) + 1;
        //3、查询当前页的数据
        int start = (pageNum - 1) * limit;
        List<Product> list = productMapper.selectProductLists(start, limit);
        return new ResultVO(ResStatus.OK, "success", new PageHelper<Product>(count, pageCount, list));
    }

    //增加商品
    @Override
    public int insertProduct(Product product) {
        logger.info("开始增加商品......");
        return productMapper.insertProduct(product);
    }

    //增加商品参数
    public int insertProductParam(ProductParams productParams) {
        logger.info("开始增加商品参数......");
        return productParamsMapper.insertProductParam(productParams);
    }

    //增加商品规格
    public int insertProductSku(ProductSku productSku) {
        logger.info("开始增加商品规格......");
        return productSkuMapper.insertProductSku(productSku);
    }

    //增加商品图片
    public int insertProductImg(ProductImg productImg) {
        logger.info("开始增加商品图片......");
        return productImgMapper.insertProductImg(productImg);
    }

    //删除商品
    @Override
    public int deleteProduct(String productId) {
        logger.info("开始删除商品......");
        List<Product> i = productMapper.queryByProductId(productId);
        if (i != null) {
            int count = productMapper.deleteProduct(productId);
        }
        return 1;
    }

    //修改商品
    @Override
    public int updateProduct(Product product) {
        logger.info("开始修改商品......");
        return productMapper.updateProduct(product);
    }

    @Override
    public int updateProductParam(ProductParams productParams) {
        logger.info("开始修改商品参数......");
        return productParamsMapper.updateProductParam(productParams);
    }

    @Override
    public int updateProductSku(ProductSku productSku) {
        logger.info("开始修改商品规格......");
        return productSkuMapper.updateProductSku(productSku);
    }

    @Override
    public int updateProductImg(ProductImg productImg) {
        logger.info("开始修改商品图片......");
        return productImgMapper.updateProductImg(productImg);
    }

    //通过商品分类id查询
    @Override
    public ResultVO getProductsByCategoryId(int classifyId, int pageNum, int limit) {
        logger.info("开始通过商品分类id查询......");
        //1.查询分页数据
        int start = (pageNum - 1) * limit;
        List<ProductVO> productVOS = productMapper.selectProductByCategoryId(classifyId, start, limit);
        //2.查询当前类别下的商品的总记录数
        Example example = new Example(Product.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("classifyId", classifyId);
        int count = productMapper.selectCountByExample(example);
        //3.计算总页数
        int pageCount = count % limit == 0 ? count / limit : count / limit + 1;
        //4.封装返回数据
        PageHelper<ProductVO> pageHelper = new PageHelper<>(count, pageCount, productVOS);
        return new ResultVO(ResStatus.OK, "SUCCESS", pageHelper);
    }

    //根据品牌查询
    @Override
    public ResultVO listBrands(int cid) {
        logger.info("开始根据品牌查询......");
        List<String> brands = productMapper.selectBrandByCategoryId(cid);
        return new ResultVO(ResStatus.OK, "success", brands);
    }

    //按关键字查询商品
    @Override
    public ResultVO searchProduct(String kw, int pageNum, int limit) {
        logger.info("开始按关键字查询商品......");
        //1.查询搜索结果
        kw = "%" + kw + "%";
        int start = (pageNum - 1) * limit;
        List<ProductVO> productVOS = productMapper.selectProductByKeyword(kw, start, limit);
        //2.查询总记录数
        Example example = new Example(Product.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andLike("productName", kw);
        int count = productMapper.selectCountByExample(example);
        //3.计算总页数
        int pageCount = count % limit == 0 ? count / limit : count / limit + 1;
        //4.封装，返回数据
        PageHelper<ProductVO> pageHelper = new PageHelper<>(count, pageCount, productVOS);
        ResultVO resultVO = new ResultVO(ResStatus.OK, "SUCCESS", pageHelper);
        return resultVO;
    }

    //根据品牌关键字查询商品
    @Override
    public ResultVO listBrands(String kw) {
        logger.info("根据品牌关键字查询商品......");
        kw = "%" + kw + "%";
        List<String> brands = productMapper.selectBrandByKeyword(kw);
        return new ResultVO(ResStatus.OK, "SUCCESS", brands);
    }

    //管理员按条件查询
    @Override
    public ResultVO selectByCondition(int pageNum,int limit,String keyWord, String productStatus, String firstClassityId) {
        logger.info("开始管理员按条件查询......");
            logger.info("开始查询商品列表......");
            //1、查询总记录数

        if(keyWord=="" && productStatus=="" && firstClassityId==""){
            Example example = new Example(Product.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("");
            int count = productMapper.selectCountByExample(example);
            //2、计算总页数
            int pageCount = count % limit == 0 ? count / limit : (count / limit) + 1;
            //3、查询当前页的数据
            int start = (pageNum - 1) * limit;
            List<Product> list = productMapper.queryByCondition(start, limit,keyWord, productStatus, firstClassityId);
            PageHelper<Product> pageHelper = new PageHelper<>(count, pageCount, list);
            return new ResultVO(ResStatus.OK,"success",pageHelper);
        }else if(productStatus!="") {
            Example example = new Example(Product.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("productStatus",productStatus);
            int count = productMapper.selectCountByExample(example);
            //2、计算总页数
            int pageCount = count % limit == 0 ? count / limit : (count / limit) + 1;
            //3、查询当前页的数据
            int start = (pageNum - 1) * limit;
            List<Product> list = productMapper.queryByCondition(start, limit,keyWord, productStatus, firstClassityId);
            PageHelper<Product> pageHelper = new PageHelper<>(count, pageCount, list);
            return new ResultVO(ResStatus.OK,"success",pageHelper);

        }else if(keyWord!=""){
            Example example = new Example(Product.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("productName",keyWord);
            int count = productMapper.selectCountByExample(example);
            //2、计算总页数
            int pageCount = count % limit == 0 ? count / limit : (count / limit) + 1;
            //3、查询当前页的数据
            int start = (pageNum - 1) * limit;
            List<Product> list = productMapper.queryByCondition(start, limit,keyWord, productStatus, firstClassityId);
            PageHelper<Product> pageHelper = new PageHelper<>(count, pageCount, list);
            return new ResultVO(ResStatus.OK,"success",pageHelper);
        }else{
            Example example = new Example(Product.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("rootCategoryId",firstClassityId);
            int count = productMapper.selectCountByExample(example);
            //2、计算总页数
            int pageCount = count % limit == 0 ? count / limit : (count / limit) + 1;
            //3、查询当前页的数据
            int start = (pageNum - 1) * limit;
            List<Product> list = productMapper.queryByCondition(start, limit,keyWord, productStatus, firstClassityId);
            PageHelper<Product> pageHelper = new PageHelper<>(count, pageCount, list);
            return new ResultVO(ResStatus.OK,"success",pageHelper);
        }

    }

    //管理员按商品状态查询
    @Override
    public ResultVO productOverview() {
        logger.info("开始管理员按商品状态查询......");
        //全部商品
        Example examples = new Example(Product.class);
        Example.Criteria criterias = examples.createCriteria();
        criterias.andEqualTo("");
        int allProduct = productMapper.selectCountByExample(examples);
        //1、已上架
        Example example = new Example(Product.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("productStatus", 1);
        int grounding = productMapper.selectCountByExample(example);
        //1、已下架
        Example example1 = new Example(Product.class);
        Example.Criteria criteria1 = example1.createCriteria();
        criteria1.andEqualTo("productStatus", 0);
        int removed = productMapper.selectCountByExample(example1);
        //3、已删除
        Example example2 = new Example(Product.class);
        Example.Criteria criteria2 = example2.createCriteria();
        criteria2.andEqualTo("productStatus", -1);
        int deleted = productMapper.selectCountByExample(example2);
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("grounding", grounding);
        hashMap.put("removed", removed);
        hashMap.put("deleted", deleted);
        hashMap.put("allProduct", allProduct);
        return new ResultVO(ResStatus.OK, "success", hashMap);
    }

    //管理员查询库存短缺的商品
    @Override
    public ResultVO inventoryShortage() {
        logger.info("开始管理员查询库存短缺的商品......");
        List<ProductSku> inventoryShortageList = productSkuMapper.selectInventoryShortage();
        int sum = 0;
        for (int i = 0; i < inventoryShortageList.size(); i++) {
            sum++;
        }
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("sum", sum);
        hashMap.put("inventoryShortageList", inventoryShortageList);
        if (inventoryShortageList.size() > 0) {
            return new ResultVO(ResStatus.OK, "success", hashMap);
        } else {
            return new ResultVO(ResStatus.NO, "fial", null);
        }
    }


}
